package org.nuist.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSONObject;
import com.graphbuilder.math.func.EFunction;
import org.bouncycastle.asn1.ocsp.ResponseData;
import org.nuist.pojo.Relation;
import org.nuist.pojo.User;
import org.nuist.pojo.VirtualMachine;
import org.nuist.service.relation.RelationServiceImpl;
import org.nuist.service.user.UserServiceImpl;
import org.nuist.service.virtualmachine.VirtualMachineServiceImpl;
import org.nuist.utils.JsonResult;
import org.nuist.utils.PageJson;
import org.nuist.utils.ShellTool.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
public class AdminController {

    @Autowired
    VirtualMachineServiceImpl virtualMachineService;

    @Autowired
    UserServiceImpl userService;

    @Autowired
    RelationServiceImpl relationService;

    @RequestMapping(value = "/admin/login",method = RequestMethod.POST)
    private JsonResult adminLogin(@RequestBody User user){
        User getUser = userService.findUserByName(user.getUserName());
        if (getUser != null) {
            if (user.getUserName().equals(getUser.getUserName()) && user.getPassword().equals(getUser.getPassword())) {
                try {
                    if (!getUser.getPerms().equals("admin")) {
                        return JsonResult.fail().set("msg", "当前账户非管理员!");
                    }
                }catch (Exception e){
                    //pass
                }
                int id = getUser.getUserId();
                return JsonResult.ok().set("userid", id);
            }
            return JsonResult.fail().set("msg","登录失败,用户名与密码不匹配!");
        }
        return JsonResult.fail().set("msg","登录失败,不存在该账号！");
    }

    /**
     * 可用虚拟机列表
     * @author DYH
     * @return PageJson
     */
    @RequestMapping(value = "/admin/freeVMList",method = RequestMethod.POST)
    private PageJson<VirtualMachine> freeVMList(){
        List<VirtualMachine> getFreeVMList=virtualMachineService.findFreeVirtualMachine();
        PageJson<VirtualMachine> pageJson=new PageJson<>();

        pageJson.setCode(0);
        pageJson.setCount(getFreeVMList.size());
        pageJson.setData(getFreeVMList);
        pageJson.setMsg("OK");
        return pageJson;
    }

    /**
     * 手动添加虚拟机
     * @author DYH
     * @param vm
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/addVM",method = RequestMethod.POST)
    private JsonResult addVM(@RequestBody VirtualMachine vm){
        VirtualMachine getVM=new VirtualMachine();
        getVM.setOccupied(vm.isOccupied());
        getVM.setPassword(vm.getPassword());
        getVM.setUserName(vm.getUserName());
        getVM.setPort(vm.getPort());
        getVM.setIp(vm.getIp());
        getVM.setStatus(vm.getStatus());
        getVM.setBootDisk(vm.getBootDisk());
        getVM.setMem(vm.getMem());
        virtualMachineService.save(getVM);
        return JsonResult.ok();
    }

    /**
     * 分配虚拟机
     * @author DYH
     * @param vmId
     * @param userId
     * @return assignVM
     */
    @RequestMapping(value = "/admin/assignVM",method = RequestMethod.POST)
    private JsonResult assignVM(@RequestParam(value = "vmId",required = true) Integer vmId,@RequestParam(value = "userId",required = true) Integer userId){

          VirtualMachine getVM=virtualMachineService.findVirtualMachineById(vmId);
          User getUser=userService.findUserById(userId);

          try {
              if (relationService.hasUser(getUser.getUserId()) == 1) {
                  return JsonResult.fail().set("msg", "该用户已经绑定虚拟机");
              }
          }catch (Exception e) {
              //pass
          }
          try{
              if (relationService.hasVM(getVM.getVirtualMachineId()) == 1) {
                  return JsonResult.fail().set("msg", "该虚拟机已经绑定用户");
              }
          }catch (Exception e){
              //pass
          }

          getVM.setOccupied(true);
          virtualMachineService.modifyVirtualMachine(getVM);

          try{
              if(!getUser.getPerms().equals("admin")) {
                  getUser.setPerms("available");
                  userService.save(getUser);
              }
          }catch (Exception e){
              //pass
          }

          Relation relation=new Relation(getUser,getVM);


          relationService.save(relation);

          return JsonResult.ok();
    }

    /**
     * 管理员操作录入学生获得空闲虚拟机表
     * @author DYH
     * @param user
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/registerByHand",method = RequestMethod.POST)
    public JsonResult registerByHand(@RequestBody User user){
        if (userService.findUserByName(user.getUserName()) != null) {
            return JsonResult.fail("注册失败,该用户名已被注册!请更换用户名重试！");
        } else {
            User getUser = new User();
            getUser.setUserName(user.getUserName());
            getUser.setPassword(user.getPassword());
            getUser.setStudentId(user.getStudentId());
            getUser.setMajor(user.getMajor());
            getUser.setPerms("notAvailable");
            userService.save(getUser);

            return JsonResult.ok().set("returnUrl", "/virtualMachine");
        }
    }

    /**
     * 根据Excel表格录入学生信息
     * @author DYH
     * @param file
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/registerByExcel",method = RequestMethod.POST)
    private JsonResult registerByExcel(@RequestParam("file") MultipartFile file){

        if (file.isEmpty()) {
            System.out.println("文件为空！");
            return JsonResult.fail().set("msg","文件为空");
        }
        // 1.获取上传文件输入流
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("开始导入");

        //读取Excel中所有行和列，都用列表表示
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        //别名在返回原来的名字
        reader.addHeaderAlias("姓名", "userName");
        reader.addHeaderAlias("密码", "password");
        reader.addHeaderAlias("专业", "major");
        reader.addHeaderAlias("学号", "studentId");

        List<User> readAll = reader.read(0, 1, reader.getRowCount(),User.class);
        int count=0;
        //for循环向数据库添加数据
        for (int i = 0; i < readAll.size(); i++) {
            User user = readAll.get(i);
            //查询数据是否出现
            if(userService.findUserByName(user.getUserName())==null){
                user.setPerms("notAvailable");
                userService.save(user);
                count++;
            }
        }

        return JsonResult.ok().set("msg","成功录入了"+count+"个学生信息");
    }

    /**
     * 获得学生表
     * @author DYH
     * @return PageJson
     */
    @RequestMapping(value = "/admin/studentList",method = RequestMethod.POST)
    private PageJson<User> useList(){
        List<User> userList=userService.findAll();
        PageJson<User> pageJson=new PageJson<>();
        pageJson.setCode(0);
        pageJson.setCount(userList.size());
        pageJson.setData(userList);
        pageJson.setMsg("OK");
        return pageJson;
    }

    /**
     * 删除虚拟机
     * @author DYH
     * @param vm
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/deleteVM",method = RequestMethod.POST)
    private JsonResult deleteVM(@RequestBody VirtualMachine vm){
        VirtualMachine getVM=virtualMachineService.findVirtualMachineById(vm.getVirtualMachineId());
        try {
            if (getVM != null) {
                if (relationService.hasVM(getVM.getVirtualMachineId()) == 1) {
                    Integer vmId = getVM.getVirtualMachineId();
                    Relation getRelation = relationService.findRelationByVMId(vmId);
                    User getUser = getRelation.getUser();
                    getUser.setPerms("notAvailable");
                    userService.save(getUser);
                    relationService.delete(getRelation);
                }
                virtualMachineService.delete(getVM);
            }
        }catch (Exception e){
            //pass
        }
        return JsonResult.ok();
    }

    /**
     * 批量删除学生
     * @author DYH
     * @param ids
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/deleteStudent",method = RequestMethod.POST)
    private JsonResult deleteStudent(@RequestParam("ids") String ids){
        List<String> idList= Arrays.asList(ids.split(","));

        for(int i=0;i< idList.size();i++) {
            Integer userId=Integer.parseInt(idList.get(i));
            try{
                if(relationService.hasUser(userId)==1){
                    Relation getRelation=relationService.findRelationByUserId(userId);
                    VirtualMachine getVM = getRelation.getVirtualMachine();
                    getVM.setOccupied(false);
                    virtualMachineService.delete(getVM);
                    relationService.delete(relationService.findRelationByUserId(userId));
                }
            }catch (NullPointerException e){
                //pass
            }
            User getUser=userService.findUserById(userId);
            if (getUser != null) {
                userService.delete(getUser);
            }
        }
        return JsonResult.ok();
    }

    /**
     * 解绑用户和虚拟机
     * @author DYH
     * @param userId
     * @param vmId
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/unbind",method = RequestMethod.POST)
    private JsonResult unbind(@RequestParam(value = "userId",required = false) Integer userId, @RequestParam(value = "vmId",required = false)Integer vmId){
             try {
                 if (relationService.hasUser(userId) == 1) {
                     Relation getRelation = relationService.findRelationByUserId(userId);
                     User getUser= userService.findUserById(userId);
                     if(!getUser.getPerms().equals("admin")) {
                         getUser.setPerms("notAvailable");
                         userService.save(getUser);
                     }
                     VirtualMachine getVM=getRelation.getVirtualMachine();
                     getVM.setOccupied(false);
                     virtualMachineService.save(getVM);
                     relationService.delete(getRelation);
                     return JsonResult.ok().set("msg","根据userId删除");
                 }
             }catch(Exception e){
                 //pass
             }
             try {
                 if (relationService.hasVM(vmId) == 1) {
                     Relation getRelation = relationService.findRelationByVMId(vmId);
                     User getUser = getRelation.getUser();
                     if(!getUser.getPerms().equals("admin")) {
                         getUser.setPerms("notAvailable");
                         userService.save(getUser);
                     }
                     VirtualMachine getVM = virtualMachineService.findVirtualMachineById(vmId);
                     getVM.setOccupied(false);
                     virtualMachineService.save(getVM);
                     relationService.delete(getRelation);
                     return JsonResult.ok().set("msg","根据vmId删除");
                 }
             }catch (Exception e){
                 //pass
             }
        return JsonResult.fail().set("msg","解绑未成功");
    }


    /**
     *  同步真实环境虚拟机信息
     *  @author DYH
      * @return JsonResult
     */
    @RequestMapping(value = "/admin/syncVMInfo",method = RequestMethod.POST)
    private JsonResult syncVMInfo(){

        //执行封装过的shell命令
        Function function=new Function();
        JSONObject jsonObject = function.listVM();

        List<Map> jsonObjects= (List<Map>) jsonObject.get("VMLISTS");

        for (Map map : jsonObjects) {

            VirtualMachine vm=new VirtualMachine();

            String port=(String) map.get("VMID");

            VirtualMachine getVM=virtualMachineService.findVirtualMachineByPort(port);

            try {
                //在数据库中找到并且再保存虚拟机
                if (getVM != null) {

                    //ip和NAME保持一致
                    getVM.setIp((String) map.get("NAME"));
                    getVM.setStatus((String) map.get("STATUS"));

                    getVM.setMem(Integer.parseInt((String) map.get("MEM")));
                    getVM.setOccupied(false);
                    getVM.setBootDisk(Double.parseDouble((String) map.get("BOOTDISK")));

                    //保存虚拟机
                    virtualMachineService.save(getVM);

                }
            }catch (Exception e){
                //pass
            }
        }

        return JsonResult.ok();
    }

    /**
     * 重启虚拟机
     * @param port
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/rebootVMByPort",method = RequestMethod.POST)
    private JsonResult rebootVMByPort(@RequestParam String port){
        Function function=new Function();
        function.rebootVM(port);

        //检查虚拟机状态~~
        JSONObject jsonObject = function.listVM();
        if(jsonObject.get("STATUS")=="running"){
            return JsonResult.ok().set("msg","虚拟机重启成功!");
        }

        return JsonResult.fail().set("msg","虚拟机重启失败!");
    }

    /**
     * 根据端口打开虚拟机
     * @param port
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/openVMByPort",method = RequestMethod.POST)
    private JsonResult openVMByPort(@RequestParam String port) {
        Function function=new Function();
        function.openVM(port);

        //检查虚拟机状态~~
        JSONObject jsonObject = function.listVM();
        List vmList=(List) jsonObject.get("VMLISTS");
        // System.out.println(vmList);
        for (int i = 0; i < vmList.size(); i++) {
            Map vmMap=(Map) vmList.get(i);
            if(vmMap.get("VMID").equals(port)){
                if (vmMap.get("STATUS").equals("running")) {
                    VirtualMachine vm=virtualMachineService.findVirtualMachineByPort(port);
                    vm.setStatus("running");
                    virtualMachineService.save(vm);
                    return JsonResult.ok().set("msg", "虚拟机开启成功!");
                }
                else
                    return JsonResult.fail().set("msg","虚拟机开启失败!");
            }
        }
        return JsonResult.fail().set("msg","虚拟机开启失败!");
    }

    /**
     * 根据端口关闭虚拟机
     * @param port
     * @return JsonResult
     */
    @RequestMapping(value = "/admin/shutVMByPort",method = RequestMethod.POST)
    private JsonResult shutVMByPort(@RequestParam String port){
        Function function=new Function();
        function.shutVM(port);
        //检查虚拟机状态~~
        JSONObject jsonObject = function.listVM();
        List vmList=(List) jsonObject.get("VMLISTS");
        // System.out.println(vmList);
        for (int i = 0; i < vmList.size(); i++) {
            Map vmMap=(Map) vmList.get(i);
            if(vmMap.get("VMID").equals(port)){
                if (vmMap.get("STATUS").equals("stopped")) {
                    VirtualMachine vm=virtualMachineService.findVirtualMachineByPort(port);
                    vm.setStatus("stopped");
                    virtualMachineService.save(vm);
                    return JsonResult.ok().set("msg", "虚拟机关闭成功!");
                }
                else
                    return JsonResult.fail().set("msg","虚拟机关闭失败!");
            }
        }
        return JsonResult.fail().set("msg","虚拟机关闭失败!");
    }

    /**
     * 建立虚拟机快照
     * @param port
     * @param snapName
     * @return JsonResult
     */
   //  @RequestMapping(value = "/admin/buildSnapShotVM",method = RequestMethod.POST)
   // private JsonResult buildSnapShotVM(@RequestParam String port,@RequestParam String snapName){
   //      Function function=new Function();
   //      //创建真实环境快照
   //      function.snapshotVM(port,snapName);
   //      JSONObject jsonObject = function.listsnapshotVM(port);
   //      List snaplist = (List) jsonObject.get("SNAPLISTS");
   //     System.out.println(snaplist);
   //      return JsonResult.ok().set("msg","创建快照成功!");
   // }


    /**
     *
     * @param port
     * @return JsonResult
     */
   // private JsonResult listSnapShotVM(@RequestParam String port){
   //
   //     Function function=new Function();
   //     JSONObject jsonObject = function.listsnapshotVM(port);
   //
   //
   //
   // }

    /**
     * 回归初始快照
     * @param port
     * @return JsonResult
     */
    private JsonResult rollbackInit(@RequestParam String port,@RequestParam String snapName){
         Function function=new Function();
         function.rollbackSnapshot(port,snapName);
         return JsonResult.ok().set("msg",port+"回归初始状态");
    }


}
